from constants import *
import os
from means import *
import cls
import file

__height_cls = "YLBodyHeightLevelTool"
__get_stage_height_level_method = "getStageHeightLevel"
__height_param = "height"
__levels_param = "levels"
__month_param = "month"
__gender_param = "gender"

__get_male_height_level_method = "getMaleHeightLevel"
__get_female_height_level_method = "getFemaleHeightLevel"

__get_height_level_method = "getHeightLevel"

def __generateGetHeightLevelMethod(dev_language):
    parmas_list = ""
    body = ""
    result = HeightLevel.enum
    height_enum = HeightLevel(dev_language)
    if dev_language == DevLanguage.objc:
        parmas_list = [Params(__levels_param, "NSArray *"), Params(__height_param, "double")]
        body += "if (%s < [%s[0] floatValue]) return %s;\n"%(__height_param, __levels_param, height_enum.getLow())
        body += "if (%s > [%s[1] floatValue]) return %s;\n"%(__height_param, __levels_param, height_enum.getHight())
        body += "return %s;\n"%height_enum.getStand()
    else:
        parmas_list = [Params(__levels_param, "Array<Double>"), Params(__height_param, "Double")]
        body += "if (%s < %s[0]) return %s;\n"%(__height_param, __levels_param, height_enum.getLow())
        body += "if (%s > %s[1]) return %s;\n"%(__height_param, __levels_param, height_enum.getHight())
        body += "return %s;\n"%height_enum.getStand()
    return generateMethod(dev_language, __get_stage_height_level_method, parmas_list, body, result)

def __generateGenderHeightLevelMethod(dev_language, method, list_tuple):
    parmas_list = ""
    body = ""
    result = HeightLevel.enum
    height_enum = HeightLevel(dev_language)
    if dev_language == DevLanguage.objc:
        parmas_list = [Params(__month_param, "int"), Params(__height_param, "double")]
        for item in list_tuple:
            objc_list = ""
            for level in item[1]:
                objc_list += '@(%s), '%level
            objc_list = '@[%s]'%(objc_list[:-2])
            body += "if(%s <= %s) return [self %sWith%s:%s %s:%s];\n"%(__month_param, item[0], __get_stage_height_level_method, __levels_param.capitalize(), objc_list, __height_param, __height_param)
        body += "return %s\n"%height_enum.getNone()
    else:
        parmas_list = [Params(__month_param, "int"), Params(__height_param, "double")]
        for item in list_tuple:
            objc_list = ""
            for level in item[1]:
                objc_list += '%s, '%level
            objc_list = 'arrayof(%s)]'%(objc_list[:-2])
            body += "if(%s <= %s) return %s(%s: %s, %s: %s);\n"%(__month_param, item[0], __get_stage_height_level_method, __levels_param, objc_list, __height_param, __height_param)
        body += "return %s\n"%height_enum.getNone()
    return generateMethod(dev_language, method, parmas_list, body, result)

def __generateImplHeightLevelMethod(dev_language):
    parmas_list = ""
    body = ""
    result = HeightLevel.enum
    height_enum = HeightLevel(dev_language)
    if dev_language == DevLanguage.objc:
        parmas_list = [Params(__month_param, "int"), Params(__height_param, "double"), Params(__gender_param, Gender.enum)]
        body = "if (%s == %s) return [self %sWith%s:%s %s:%s];\nreturn [self %sWith%s:%s %s:%s];\n"%(__gender_param, Gender.male, __get_male_height_level_method, __month_param.capitalize(), __month_param, __height_param, __height_param, __get_female_height_level_method, __month_param.capitalize(), __month_param, __height_param, __height_param)
    else:
        parmas_list = [Params(__month_param, "Int"), Params(__height_param, "Double"), Params(__gender_param, "Int")]
        body = "if (%s == 1) return %s(%s: %s, %s: %s);\nreturn %s(%s: %s, %s: %s);\n"%(__gender_param, __get_male_height_level_method, __month_param, __month_param, __height_param, __height_param, __get_female_height_level_method, __month_param, __month_param, __height_param, __height_param)
    return generateMethod(dev_language, __get_height_level_method, parmas_list, body, result,  None if dev_language == DevLanguage.objc else "男 1 女 0")


def __generateInterHeightLevelObjcMethod():
    return "+ (%s)%sWith%s:(int)%s %s:(%s)%s %s:(double)%s;"%(HeightLevel.enum, __get_height_level_method, __month_param.capitalize(), __month_param, __gender_param, Gender.enum, __gender_param, __height_param, __height_param)

def __generateHeightLevelEnum(dev_language):
    if dev_language == DevLanguage.objc:
        height_enum = HeightLevel(DevLanguage.objc)
        return "typedef enum{\n%s = 0,\n%s = 1,\n%s = 2,\n%s = 3,\n}%s;"%(height_enum.getNone(), height_enum.getStand(), height_enum.getHight(), height_enum.getLow(), HeightLevel.enum)
    
    return "enum class %s {\n%s,\n%s,\n%s,\n%s\n}"%(HeightLevel.enum, HeightLevel.none, HeightLevel.stand, HeightLevel.high, HeightLevel.low)

def generateFile(dev_language, male_list_tuple, female_list_tuple):
    method_1 = __generateImplHeightLevelMethod(dev_language)
    method_2 = __generateGenderHeightLevelMethod(dev_language, __get_male_height_level_method, male_list_tuple)
    method_3 = __generateGenderHeightLevelMethod(dev_language, __get_female_height_level_method, female_list_tuple)
    method_4 = __generateGetHeightLevelMethod(dev_language)

    method_impl = method_1 + "\n" + method_2 + "\n" + method_3 + "\n" + method_4

    enum_str = __generateHeightLevelEnum(dev_language)

    if dev_language == DevLanguage.kotlin:
        cls_str = cls.generateKotlin(__height_cls, method_impl, enum_str)
        kt_path = file.getKtRootPath()
        cls_path = os.path.join(kt_path, __height_cls + '.kt')
        with open(cls_path, 'w+') as fs:
            fs.write(cls_str)
    else:
        method_inter = __generateInterHeightLevelObjcMethod()
        cls_impl = cls.generateObjcImpl(__height_cls, method_impl)
        cls_inter = cls.generateObjcInter(__height_cls, method_inter, enum_str)
        objc_path = file.getObjcRootPath()
        h_path = os.path.join(objc_path, __height_cls + ".h")
        m_path = os.path.join(objc_path, __height_cls + ".m")
        with open(m_path, 'w+') as fs:
            fs.write(cls_impl)

        with open(h_path, 'w+') as fs:
            fs.write(cls_inter)

def generateHeightLevelCls(ws):
    male_levels = []
    female_levels = []
    for row in ws.iter_rows(min_row = 3):
        male_month = row[1].value
        female_month = row[14].value
        if male_month == None:
            male_month = row[0].value
            male_month = int(float(male_month[:-1]) * 12)
        if female_month == None:
            female_month = row[13].value
            female_month = int(float(female_month[:-1]) * 12)

        if row[4].value != None and row[6].value != None:
            male_level = (male_month,[row[4].value, row[6].value])
            male_levels.append(male_level)
        
        if row[17].value != None and row[19].value != None:
            female_level = (female_month,[row[17].value, row[19].value])
            female_levels.append(female_level)
    
    generateFile(DevLanguage.kotlin, male_levels, female_levels)
    generateFile(DevLanguage.objc, male_levels, female_levels)
